import requests
import urllib.parse
import html
import traceback
from gravityassist.bililib import get_bilibili_params
from gravityassist.musiclib import get_music_list
from gravityassist.lang import fuzzy_search

def parse_item(item):
    if item.get('type', 'video') != 'video':
        return None
    if 'bvid' not in item:
        return None
    result = {}
    result['url'] = 'https://www.bilibili.com/video/' + item['bvid']
    if 'title' in item:
        title = item['title']
        title = title.replace('<em class="keyword">', '')
        title = title.replace('</em>', '')
        title = html.unescape(title)
        result['title'] = title
    accepts = ['duration', 'author', 'play', 'favorites']
    for key in accepts:
        if key in item:
            result[key] = item[key]
    return result

def search_music_local(query, num_results: int = 10):
    musics = get_music_list()
    musics = [music["name"] for music in musics]
    results = fuzzy_search(musics, query)[:num_results]
    results = [{'id': i, 'name': musics[i]} for i in results]
    if not results:
        return {'success': False, 'message': f'No results matching `{query}` found. Maybe use list_musics for search?'}
    return {'success': True, 'results': results}

def search_music_web(query, num_results: int = 10, duration: str = '<10'):
    params = get_bilibili_params()
    url = 'https://api.bilibili.com/x/web-interface/search/type?' + urllib.parse.urlencode({
        'keyword': query,
        'search_type': 'video',
        'duration': ['any', '<10', '10~30', '30~60', '>60'].index(duration),
    })
    r = requests.get(url, **params)
    res = r.json()
    if res['code'] != 0:
        return {'success': False, 'message': res['message']}
    results = []
    for item in res["data"]["result"]:
        result = parse_item(item)
        if result:
            results.append(result)
        if len(results) > num_results:
            break
    return {'success': True, 'results': results}

def search_music(query, num_results: int = 10, duration: str = '<10'):
    try:
        web = search_music_web(query, num_results, duration)
    except:
        traceback.print_exc()
        web = {'success': False}
    try:
        local = search_music_local(query, num_results)
    except:
        traceback.print_exc()
        local = {'success': False}
    if not web['success']:
        return local
    if not local['success']:
        return web
    return {'success': True, 'local_results': local, 'online_results': web}

if __name__ == "__main__":
    from gravityassist.config import load_persistent_data
    load_persistent_data('instance')
    results = search_music('雨歌白日梦', 99)
    print(results)
